<template>
  <edit-card :title="handleOption.title" :loading="loading" :type="(handleOption.type as 'edit'|'add')" @confirm="submit">
    <a-form ref="formRef" :model="formState" name="basic" class="my-a-form" label-align="left" :rules="rules" scroll-to-first-error>
      <a-form-item label="角色名称" name="name">
        <a-input v-model:value="formState.name" v-trim class="h-36" style="width: 440px" :maxlength="20" placeholder="请输入角色名称" />
      </a-form-item>
      <a-form-item label="教师用户" name="teacherIds">
        <a-button>添加教师</a-button>
        <a-form-item-rest>
          <g-select-tree-data
            ref="gSelectTreeDataTeacherRef"
            v-model:checkedIds="formState.teacherIds"
            :has-collect="false"
            type-name="请选择教师"
            select-data-type="file"
            :node-icon="{ folder: 'icon-group-line', file: 'icon-user-line' }"
            :get-tree-data-api="roleApi.teacherTree"
            :get-list-data-api="roleApi.teacherList"
          >
            <template #resultTotal="{ fileNum }"> {{ fileNum }}个人 </template>
          </g-select-tree-data>
        </a-form-item-rest>
      </a-form-item>
      <a-form-item label="数据权限" name="dataType">
        <div class="pt-2 pb-8">
          <a-radio-group v-model:value="formState.dataType" :options="dataTypeOptions" />
        </div>
        <div v-show="formState.dataType === 3">
          <a-form-item-rest>
            <g-select-tree-data
              ref="gSelectTreeDataOrgRef"
              v-model:checkedIds="formState.orgIds"
              :has-collect="false"
              type-name="请选择组织"
              :node-icon="{ folder: 'icon-group-line', file: 'icon-group-line' }"
              :get-tree-data-api="roleApi.orgTree"
              :get-list-data-api="roleApi.orgList"
            >
              <template #resultTotal="{ folderNum, fileNum }"> {{ folderNum + fileNum }}个组织 </template>
            </g-select-tree-data>
          </a-form-item-rest>
        </div>
      </a-form-item>
      <a-form-item name="rolePermissions" label="角色权限">
        <a-form-item-rest>
          <auth-menu-select v-if="childrenTree.length" ref="authMenuSelectRef" :menu-data="childrenTree" />
        </a-form-item-rest>
      </a-form-item>
    </a-form>
  </edit-card>
</template>

<script lang="ts" setup>
  import { message } from 'ant-design-vue'
  import type { Rule } from 'ant-design-vue/es/form'
  import { regex } from 'g6-fn'
  import { computed, reactive, ref } from 'vue'
  import { useRoute, useRouter } from 'vue-router'

  import EditCard from '@/components/EditCard/index.vue'
  import GSelectTreeData from '@/components/GSelectTreeData/index.vue'
  import { menuApi, roleApi } from '@/services/api'

  import AuthMenuSelect from '../components/AuthMenuSelect.vue'
  import { MenuItem, RoleDetail, RoleForm } from '../types'

  const dataTypeOptions = [
    { label: '所属组织和下级组织', value: 1 },
    { label: '所有组织', value: 2 },
    { label: '自定义', value: 3 }
  ]

  const route = useRoute()
  const router = useRouter()

  const editRoleId = route.params.id as string
  const initName = ref() //初始化角色名称
  const pageOptions = computed(() => {
    return {
      add: {
        title: '创建角色',
        type: 'add',
        text: '新增',
        handleApi: roleApi.add
      },
      edit: {
        title: `编辑角色（${initName.value}）`,
        type: 'edit',
        text: '编辑',
        handleApi: roleApi.edit
      }
    }
  })

  let handleOption = computed(() => pageOptions.value[editRoleId ? 'edit' : 'add'])

  const formRef = ref()
  const formState = reactive<RoleForm>({
    id: editRoleId,
    name: '',
    dataType: 1,
    orgIds: [],
    menusIds: [],
    teacherIds: []
  })
  const childrenTree = ref<MenuItem[]>([]) //菜单数据
  const authMenuSelectRef = ref<InstanceType<typeof AuthMenuSelect>>()
  const gSelectTreeDataTeacherRef = ref<InstanceType<typeof GSelectTreeData>>()
  const gSelectTreeDataOrgRef = ref<InstanceType<typeof GSelectTreeData>>()

  const rules: Record<string, Rule[]> = {
    name: [
      { required: true, message: '请输入角色名称' },
      {
        pattern: regex.name,
        message: '仅支持中英文、数字'
      }
    ],
    dataType: [
      {
        validator: () => {
          if (formState.dataType === 3 && formState.orgIds.length === 0) {
            return Promise.reject('请选择组织')
          }

          return Promise.resolve()
        },
        trigger: 'change',
        required: true
      }
    ],
    rolePermissions: [
      {
        validator: () => {
          const selectMenuIds = authMenuSelectRef.value?.selectAllChildren || []
          if (selectMenuIds.length === 0) {
            return Promise.reject('请选择角色权限')
          }
          return Promise.resolve()
        },
        required: true
      }
    ]
  }

  // 提交表单
  const loading = ref(false)
  const submit = async () => {
    await formRef.value.validateFields()

    try {
      formState.menusIds = authMenuSelectRef.value?.selectAllChildren || []
      loading.value = true
      await handleOption.value.handleApi(formState, { isAddUid: true })
      message.success('操作成功')
      router.back()
    } finally {
      loading.value = false
    }
  }

  // 新增初始化
  const initAddMenu = async () => {
    const res = await menuApi.allList()
    childrenTree.value = res.data
  }

  // 编辑初始化
  const initEditMenu = async () => {
    const { data: detailRes } = (await roleApi.detail({}, { urlParams: { id: formState.id } })) as ResponseData<RoleDetail>

    initName.value = detailRes.name

    formState.name = detailRes.name
    formState.dataType = detailRes.dataType
    childrenTree.value = detailRes.childrenTree

    // 回显选择教师
    detailRes.teacherList.forEach(it => {
      gSelectTreeDataTeacherRef.value?.addKey({
        key: it.id,
        title: it.name,
        isLeaf: it.type === 1
      })
    })

    if (detailRes.dataType === 3) {
      // 回显数据权限-》选择组织
      detailRes.orgList.forEach(it => {
        gSelectTreeDataOrgRef.value?.addKey({
          key: it.id,
          title: it.name,
          isLeaf: it.type === 1
        })
      })
    }
  }

  const init = async () => {
    await (formState.id ? initEditMenu : initAddMenu)()
  }

  init()
</script>

<style lang="less" scoped>
  @import '@/styles/mixins.less';

  .my-a-form {
    width: 800px;

    .ant-form-item {
      margin-bottom: 40px;
      // 调整表单项间距之后，需考虑到出现错误提示的字段的高度，为24px000
      &.ant-form-item-with-help {
        margin-bottom: 16px;
      }

      :deep(.ant-form-item-label) {
        width: 120px;

        & > label {
          &::after {
            display: none;
          }
        }
      }
    }

    .ant-form-item:last-of-type {
      margin-bottom: 0;
    }

    .auth-module {
      display: flex;
      width: 100%;

      .auth-select-title {
        margin-bottom: 8px;
        width: 120px;
        color: @text02;
        .font14();
        // 黑色星号*
        &::after {
          display: inline-block !important;
          font-size: 14px;
          font-family: SimSun, sans-serif;
          color: @text02;
          font-weight: 700;
          line-height: 1;
          content: '*';
          transform: translate(2px, -1px);
        }
      }

      .ant-collapse {
        background-color: #fff;
        border: none;
        flex: 1;

        .ant-collapse-item {
          overflow: hidden;
          border: 1px solid @border2;
          border-radius: 6px;

          :deep(.ant-collapse-header) {
            align-items: center;
            padding-right: 12px;
            // padding: 12px 8px 12px;
            padding-left: 8px;
            height: 54px;

            .my-a-collapse-header {
              width: 100%;
              height: 100%;

              .header-title {
                .font14b();

                color: @text01;
              }

              .header-num {
                color: @text02;

                &.disabled {
                  color: @text04;
                }
              }
            }
          }

          :deep(.ant-collapse-content-box) {
            padding: 0;
          }

          & + .ant-collapse-item {
            margin-top: 16px;
          }
        }

        .iconfont {
          margin-right: 4px;
          font-size: 20px;

          &.rotate-90 {
            transform: rotate(90deg);
          }
        }
      }
    }

    .form-footer {
      margin-top: 64px;
    }
  }
</style>
